package com.shyt.api;


import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.shyt.dao.*;
import com.shyt.filter.annotation.RecordLogsAspectAt;
import com.shyt.impl.SysPermissionServiceImpl;
import com.shyt.impl.SysUserServiceImpl;
import com.shyt.security.AuthUserDetailUtil;
import com.shyt.util.ApiResponse;
import com.shyt.util.MenuUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.stream.Collectors;

@RestController
@Slf4j
@RequestMapping("api/")
@CrossOrigin
public class SysUserApi {
    @Autowired
    SysPermissionServiceImpl sysPermissionService;
    @Autowired
    SysUserServiceImpl sysUserServiceImpl;
    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    AuthenticationManagerBuilder authenticationManagerBuilder;

    @Autowired
    AuthUserDetailUtil authUserDetailUtil;

    @Autowired
    BCryptPasswordEncoder bCryptPasswordEncoder;

    @RecordLogsAspectAt
    @PostMapping("getLoginUserInfoVo")
    public ApiResponse getLoginUserInfoVo() throws Exception {
        Authentication authentication =
                SecurityContextHolder.getContext().getAuthentication();
        if (null == authentication) {
            throw new Exception("用户信息为空，用户信息有误，请联系管理员");
        }
        SysUserVo sysUserVo = (SysUserVo) authentication.getPrincipal();
        if (null == sysUserVo) {
            return null;
        }
        List<SysPermissionVo> permissionList = sysUserVo.getPermissionList();
        List<String> roles = permissionList.stream()
                .filter(item -> !StringUtils.isEmpty(item.getCode()))
                .map(SysPermissionVo::getCode).collect(Collectors.toList());

        DlrUserInfoVo dlrUserInfoVo = new DlrUserInfoVo();
        dlrUserInfoVo.setId(sysUserVo.getId());
        dlrUserInfoVo.setRoles(roles);
        dlrUserInfoVo.setUserId(sysUserVo.getId());
        dlrUserInfoVo.setUserNm(sysUserVo.getUsername());
        //return new ApiResponse("200", "调用成功", dlrUserInfoVo);
        return ApiResponse.ok(dlrUserInfoVo);
    }

    @RecordLogsAspectAt
    @PostMapping("getLoginMenuInfoVo")
    public ApiResponse getLoginMenuInfoVo() throws Exception {
        Authentication authentication =
                SecurityContextHolder.getContext().getAuthentication();
        if (null == authentication) {
            throw new Exception("用户信息为空，用户信息有误，请联系管理员");
        }
        SysUserVo sysUserVo = (SysUserVo) authentication.getPrincipal();
        if (null == sysUserVo) {
            return null;
        }


        List<SysPermissionVo> permissionList = sysUserVo.getPermissionList();

        MenuUtil menuUtil = new MenuUtil();
        List<SysPermissionVo> menus = menuUtil.getMenu(permissionList);
        //return new ApiResponse("200", "调用成功", menus);
        return ApiResponse.ok(menus);
    }

    @RecordLogsAspectAt
    @PostMapping("getLoginRouterInfoVo")
    public ApiResponse getLoginRouterInfoVo() throws Exception {
        Authentication authentication =
                SecurityContextHolder.getContext().getAuthentication();
        if (null == authentication) {
            throw new Exception("用户信息为空，用户信息有误，请联系管理员");
        }
        SysUserVo sysUserVo = (SysUserVo) authentication.getPrincipal();
        if (null == sysUserVo) {
            return null;
        }


        List<SysPermissionVo> permissionList = sysUserVo.getPermissionList();

        permissionList = permissionList.stream().filter(
                item -> (!"2".equals(String.valueOf(item.getType())))).collect(Collectors.toList());
        List<RouterVo> routerVos = MenuUtil.makeRouter(permissionList, 0l);

        //return new ApiResponse("200", "调用成功", routerVos);
        return ApiResponse.ok(routerVos);
    }

    @RecordLogsAspectAt
    @PostMapping("loginOut")
    public ApiResponse loginOut() throws Exception {
        Authentication authentication =
                SecurityContextHolder.getContext().getAuthentication();
        if (null == authentication) {
            throw new Exception("用户信息为空，用户信息有误，请联系管理员");
        }
        SysUserVo sysUserVo = (SysUserVo) authentication.getPrincipal();
        if (null == sysUserVo) {
            return null;
        }

        Map<String, String> entries = redisTemplate.opsForHash().entries("tokenSession");
        if (null != entries) {
            for (String key : entries.keySet()) {
                if (sysUserVo.getUsername().equals(entries.get(key))) {
                    redisTemplate.opsForHash().delete("tokenSession", key);
                }
            }
        }

        //return new ApiResponse("200", "调用成功", "");
        return ApiResponse.ok("");
    }

    @RecordLogsAspectAt
    @PostMapping("selectAllUsers")
    public ApiResponse selectAllUsers(@RequestBody SysUserVo sysUserVo) throws Exception {
        List<SysUserVo> sysUserVos = sysUserServiceImpl.selectAllUsers(sysUserVo);
        //return new ApiResponse("200", "调用成功", sysUserVos);
        return ApiResponse.ok(sysUserVos);
    }

    @PostMapping("deleteYh")
    public ApiResponse deleteYh(@RequestBody SysUserVo sysUserVo) throws Exception {
        sysUserServiceImpl.deleteYh(sysUserVo);
        //return new ApiResponse("200", "调用成功", "");
        return ApiResponse.ok("");
    }

    @RecordLogsAspectAt
    @PostMapping("addUser")
    public ApiResponse addUser(@RequestBody SysUserVo sysUserVo) throws Exception {

        sysUserVo.setId(getLong(new Random(), 100000l));
        sysUserVo.setCreateTime(new Date());
        sysUserVo.setUpdateTime(new Date());
        sysUserVo.setPassword(bCryptPasswordEncoder.encode(sysUserVo.getPassword()));

        sysUserServiceImpl.addUser(sysUserVo);
        sysUserServiceImpl.addRoles(sysUserVo.getRoles(), sysUserVo.getId());

        //return new ApiResponse("200", "调用成功", "");
        return ApiResponse.ok("");
    }

    @RecordLogsAspectAt
    @PostMapping("editUser")
    public ApiResponse editUser(@RequestBody SysUserVo sysUserVo) throws Exception {

        sysUserVo.setUpdateTime(new Date());
        //sysUserVo.setPassword(bCryptPasswordEncoder.encode(sysUserVo.getPassword()));
        //用户修改
        sysUserServiceImpl.editUser(sysUserVo);

        //编辑角色
        sysUserServiceImpl.addRoles(sysUserVo.getRoles(), sysUserVo.getId());

        //return new ApiResponse("200", "调用成功", "");
        return ApiResponse.ok("");
    }

    @RecordLogsAspectAt
    @PostMapping("selectAllRoles")
    public ApiResponse selectAllRoles() throws Exception {

        List<SysRoleVo> sysRoleVos = sysUserServiceImpl.selectAllRoles();

        List<Map> rtnList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(sysRoleVos)) {
            sysRoleVos.stream().forEach(item -> {
                Map<String, String> rtnMap = new HashMap<>();
                rtnMap.put("value", item.getId());
                rtnMap.put("label", item.getRoleName());
                rtnList.add(rtnMap);
            });
        }
        //return new ApiResponse("200", "调用成功", rtnList);
        return ApiResponse.ok(rtnList);
    }

    @RecordLogsAspectAt
    @PostMapping("selectAllRolesHasAl")
    public ApiResponse selectAllRolesHasAl(@RequestBody SysUserVo sysUserVo) throws Exception {

        List<SysRoleVo> sysRoleVos = sysUserServiceImpl.selectAllRolesHasAl(sysUserVo.getId());

        List<Map> rtnList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(sysRoleVos)) {
            sysRoleVos.stream().forEach(item -> {
                Map<String, String> rtnMap = new HashMap<>();
                rtnMap.put("value", item.getId());
                rtnMap.put("label", item.getRoleName());
                rtnList.add(rtnMap);
            });
        }
        //return new ApiResponse("200", "调用成功", rtnList);
        return ApiResponse.ok(rtnList);
    }

    @RecordLogsAspectAt
    @PostMapping("selectDepartmentsForUser")
    public ApiResponse selectDepartmentsForUser() throws Exception {
        List<SysDepartmentVo> sysDepartmentVos = sysUserServiceImpl.selectDepartmentsForUser();
        List<Map> rtnList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(sysDepartmentVos)) {
            sysDepartmentVos.stream().forEach(item -> {
                Map<String, String> rtnMap = new HashMap<>();
                rtnMap.put("value", item.getId());
                rtnMap.put("label", item.getDepartmentName());
                rtnList.add(rtnMap);
            });
        }
        //return new ApiResponse("200", "调用成功", rtnList);
        return ApiResponse.ok(rtnList);
    }

    public long getLong(Random random, long n) {
        long bits, val;
        do {
            bits = (random.nextLong() << 1) >>> 1;
            val = bits % n;
        } while (bits - val + (n - 1) < 0l);
        return val;
    }

}
